//
//  AMHttpRequest.m
//  WeiDu_1_0
//
//  Created by foguo-mac-1 on 01/07/16.
//  Copyright (c) 2016 WeiDu Energy Tech. All rights reserved.
//

#import "HOHttpRequest.h"
#import "Logger.h"
#import "HOResponseFactory.h"
#import "HOConstants.h"

@implementation HOHttpRequest
@synthesize delegate;

- (instancetype)init
{
    if(self = [super init])
    {
        requestedData = [[NSMutableData alloc] init];
    }
    return self;
}

- (void)doRequest:(HOBaseRequestEntity *)request;
{
    if(isCanceled == YES)
    {
        return;
    }
    self.baseRequest = request;
    self.baseRequest.requestTimes ++;
	
	NSString* actionName = [self.baseRequest.params objectForKey:kHO_FIELD_Action];
	if(actionName == nil)
	{
		return;
	}
	self.baseRequest.action = actionName;
	
	NSMutableString *urlStr = [NSMutableString stringWithString:[NSString stringWithFormat:@"%@/%@", [self.baseRequest getFullURL], actionName]];
	NSString *fullUrl = [self.baseRequest.params objectForKey:kHO_FIELD_FullUrl];
	if(fullUrl)
	{
		urlStr = [NSMutableString stringWithFormat:@"%@%@?", fullUrl, actionName];
	}
	
	if([[self.baseRequest getMethod] isEqualToString:@"Get"])
	{
		NSMutableDictionary *fullDic = [NSMutableDictionary dictionaryWithDictionary:self.baseRequest.params];
		[fullDic removeObjectForKey:kHO_FIELD_Action];
		[fullDic removeObjectForKey:kHO_FIELD_Method];
		[fullDic removeObjectForKey:kHO_FIELD_FullUrl];
		[fullDic removeObjectForKey:kHO_FIELD_Service];
		[fullDic removeObjectForKey:kHO_FIELD_Token];
		
		for(int i = 0; i < [[fullDic allKeys] count]; i ++)
		{
			NSString *key = [[fullDic allKeys] objectAtIndex:i];
			if(i == 0)
			{
				NSString *value = [self.baseRequest.params objectForKey:key];
				[urlStr appendFormat:@"%@=%@", key, value];
			}
			else
			{
				NSString *value = [self.baseRequest.params objectForKey:key];
				[urlStr appendFormat:@"&%@=%@", key, value];
			}
			
		}
		urlStr = [NSMutableString stringWithString:[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
		LogInf(@"urlStr:%@", urlStr);
		LogImp(@"*****************************************");
	}
    self.asiRequest = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:urlStr]];
	
    [self.asiRequest setRequestMethod:[self.baseRequest getMethod]];
    self.asiRequest.timeOutSeconds = 180;
	NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
	[dic setObject:actionName forKey:kHO_FIELD_Action];
    if([[self.baseRequest getMethod] isEqualToString:@"POST"])
    {
		
        for(NSString *key in [self.baseRequest.params allKeys])
		{
			[self.asiRequest addPostValue:[self.baseRequest.params objectForKey:key] forKey:key];
			if([key isEqualToString:kHO_FIELD_FaultImage]
			   || [key isEqualToString:kHO_FIELD_FaultVoice])
			{
				NSString *value = [request.params objectForKey:key];
				NSInteger length = value.length;
				[dic setObject:[NSString stringWithFormat:@"send length:%lu KB", (length / 1024)] forKey:key];
			}
			else if([key isEqualToString:kHO_FIELD_Token])
			{
			}
			else
			{
				[dic setObject:[self.baseRequest.params objectForKey:key] forKey:key];
			}
		}
		if([actionName isEqualToString:kHO_ACTION_Login])
		{
			LogInf(@"请求参数:%@", dic);
		}
		[dic release];
		LogInf(@"urlStr:%@", urlStr);
        LogImp(@"*****************************************");
    }
	else
	{
		
		[dic release];
	}
    if(IS_MORETHAN_IOS8)
        self.asiRequest.name = [NSString stringWithFormat:@"%d", self.baseRequest.sequence];
    [self.asiRequest addRequestHeader:@"Content-Type" value:@"application/json; encoding=utf-8"];
    [self.asiRequest addRequestHeader:@"Accept" value:@"application/json"];
    [self.asiRequest setRequestMethod:@"POST"];
    self.asiRequest.delegate = self;
//    LogInf(@"self.asiRequest self.asiRequest.delegate:%@, self.asiRequest:%@", self.asiRequest.delegate, self.asiRequest);
    [self.asiRequest setDefaultResponseEncoding:NSUTF8StringEncoding];
    [self.asiRequest setResponseEncoding:NSUTF8StringEncoding];
    [self.asiRequest setShouldAttemptPersistentConnection:NO];
	[self.asiRequest setUploadProgressDelegate:self];
    [self.asiRequest setDownloadProgressDelegate:self];
//    [self.asiRequest setDidFailSelector:@selector(urlRequestSucceeded:)];
//    [self.asiRequest setDidFinishSelector:@selector(urlRequestFailed:)];
    //    [self.asiRequest setShowAccurateProgress:YES];
//    LogInf(@"self.asiRequest startAsynchronous----");
    [self.asiRequest startAsynchronous];
}
		
- (void)urlRequestSucceeded:(ASIHTTPRequest *)request
{
//    LogInf(@"urlRequestSucceeded:%@", request);
}
		
- (void)urlRequestFailed:(ASIHTTPRequest *)request
{
    NSError *error = [request error];
    LogInf(@"error:%@", error);
    LogInf(@"urlRequestFailed:%@", request);
}




- (void)requestStarted:(ASIHTTPRequest *)request
{
    if(self.asiRequest == nil)
        return;
    self.baseRequest.status = HO_REQUEST_STATUS_DOING;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance] getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
    if(self.asiRequest == nil)
        return;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
//                                           getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}
- (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL
{
    if(self.asiRequest == nil)
        return;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
//                                           getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
#ifdef isTestingMode
    LogInf(@"AMHttpRequest requestFinished!:%@", request.responseString);
#endif
    if(self.asiRequest == nil)
        return;
//    NSError *error1 = [self.asiRequest error];
//    if (!error1) {
//        NSString *response = [self.asiRequest responseString];
//    }
    HOBaseResponseEntity *baseResponse = [[[HOResponseFactory sharedInstance]
                                           getResponseWithRequest:self.baseRequest] retain];

	id type = [self.baseRequest.params objectForKey:kHO_FIELD_Service];
	HO_SERVICE_TYPE serviceType = type == NULL ? HO_SERVICE_WEIDU : [type intValue];
    [baseResponse verifyResponseData:[request responseData] withWithServiceType:serviceType];
//    LogInf(@"requestFinished requestedData:%@", requestedData);
//    LogInf(@" baseResponse.errorCode:%d",  baseResponse.errorCode);
    self.baseRequest.status =  [baseResponse getErrorCode] == ERROR_CODE_NON? HO_REQUEST_STATUS_DONE : HO_REQUEST_STATUS_FAILED;
//    LogInf(@"self.baseRequest.errorCode:%d",  (int)baseResponse.errorCode);
//    LogInf(@"self.baseRequest.status:%d",  (int)self.baseRequest.status);
//    LogInf(@"self.baseRequest.action:%@",  self.baseRequest.action);
    if([self.delegate respondsToSelector:@selector(didReceiveResponse:)])
    {
        [self.delegate didReceiveResponse:baseResponse];   
    }
    [baseResponse release];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
    LogInf(@"HOHttpRequest requestFailed!");
    if(self.asiRequest == nil)
        return;
    self.baseRequest.status = HO_REQUEST_STATUS_FAILED;
    HOBaseResponseEntity *baseResponse = [[[HOResponseFactory sharedInstance]
                                           getResponseWithRequest:self.baseRequest] retain];
    baseResponse.error = request.error;
//	NSLog(@"request.error:%@" , request.error);
    if(baseResponse.error.code == 2)
    {
		[baseResponse setErrorCode:ERROR_CODE_NETWORK_DOWN];

    }
    else if(baseResponse.error.code == 1)
    {
		[baseResponse setErrorCode:ERROR_CODE_SERVER_DOWN];
    }
	if(baseResponse.apiError.errorMessage == nil)
	{
		baseResponse.apiError.errorMessage = [baseResponse.error.userInfo objectForKey:NSLocalizedDescriptionKey];
	}
	
    if([self.delegate respondsToSelector:@selector(didReceiveResponse:)])
    {
        [self.delegate didReceiveResponse:baseResponse];
    }
    [baseResponse release];
}
- (void)requestRedirected:(ASIHTTPRequest *)request
{
    if(self.asiRequest == nil)
        return;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
//                                           getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}

// When a delegate implements this method, it is expected to process all incoming data itself
// This means that responseData / responseString / downloadDestinationPath etc are ignored
// You can have the request call a different method by setting didReceiveDataSelector
//- (void)request:(ASIHTTPRequest *)request didReceiveData:(NSData *)data
//{
//    if(self.asiRequest == nil)
//        return;
//    [requestedData appendData:data];
////    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
////                                           getResponseWithRequest:self.baseRequest] retain];
////    [baseResponse release];
//}

// If a delegate implements one of these, it will be asked to supply credentials when none are available
// The delegate can then either restart the request ([request retryUsingSuppliedCredentials]) once credentials have been set
// or cancel it ([request cancelAuthentication])
- (void)authenticationNeededForRequest:(ASIHTTPRequest *)request
{
    if(self.asiRequest == nil)
        return;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
//                                           getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}
- (void)proxyAuthenticationNeededForRequest:(ASIHTTPRequest *)request
{
    if(self.asiRequest == nil)
        return;
//    AMBaseResponseEntity *baseResponse = [[[AMResponseFactory sharedInstance]
//                                           getResponseWithRequest:self.baseRequest] retain];
//    [baseResponse release];
}


- (void)setProgress:(float)newProgress
{
    if(self.asiRequest == nil)
        return;
    self.baseRequest.progress = newProgress * 100;
//	NSLog(@"self.baseRequest.progress:%d action:%@", self.baseRequest.progress, self.baseRequest.action);
	self.baseRequest.status = HO_REQUEST_STATUS_DOING;
	HOBaseResponseEntity *baseResponse = [[[HOResponseFactory sharedInstance]
										   getResponseWithRequest:self.baseRequest] retain];
	if([self.delegate respondsToSelector:@selector(didReceiveResponse:)])
	{
		[self.delegate didReceiveResponse:baseResponse];
	}
	[baseResponse release];

}

- (void)request:(ASIHTTPRequest *)request didSendBytes:(long long)bytes
{
//	NSLog(@"didSendBytes bytes:%llu", bytes);
}
- (void)cancelRequest
{
//    if(isCanceled
//       || self.baseRequest.status == HO_REQUEST_STATUS_DONE
//       || self.baseRequest.status == HO_REQUEST_STATUS_FAILED)
//        return;
    isCanceled = YES;
    self.baseRequest.status = HO_REQUEST_STATUS_CANCELED;
    if(self.asiRequest == nil)
        return;
    
    if(self.asiRequest.isCancelled)
    {
//        LogInf(@"self.asiRequest.isCancelled!");
    }
    if(self.asiRequest.isExecuting)
    {
//        LogInf(@"self.asiRequest.isExecuting!");
        [self.asiRequest clearDelegatesAndCancel];
    }
    
    if(self.asiRequest.isFinished)
    {
//        LogInf(@"self.asiRequest.isFinished!");
    }
	self.asiRequest = nil;;
//    LogInf(@"self.asiRequest = nil");
    self.asiRequest = nil;
}
- (void)cleanup
{
    [self cancelRequest];
    self.baseRequest = nil;
	self.asiRequest = nil;
    self.delegate = nil;
}

#pragma mark
- (void)dealloc
{
    [self cleanup];
	[requestedData release];
	requestedData = nil;
	self.asiRequest = nil;
    [super dealloc];
}
@end
